// 要求程序运行后，给出六个菜单项的内容和输入提示
// 1. 通信录链表的建立
// 2. 通信者结点的插入
// 3. 通信者结点的查询
// 4. 通信者结点的删除
// 5. 通信录结点的输出
// 6. 退出管理系统

/***************************************/
/*     主控菜单处理测试程序 main2.c    */
/***************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct          // 定义通信录结点类型
{
  char num[5];          // 编号
  char name[9];        // 姓名
  char sex[3];            // 性别
  char phone[13];    // 电话
  char addr[31];         // 地址
} DataType;

typedef struct node // 定义结点的类型
{
  DataType data;      // 定义结点的数据域
  struct node *next; // 定义结点的指针域
} ListNode;

typedef ListNode *LinkList; // 定义LinkList
LinkList head;
ListNode *p;

// 函数声明
// int menu_select();
// LinkList CreateList(void);
// void InsertNode(LinkList head, ListNode *p);
// ListNode *ListFind(LinkList head);
// void DelNode(LinkList head);
// void PrintList(LinkList head);


/***************************************/
/*                    输出主控菜单                 */
/***************************************/
int menu_select()
{
  int sn;
  printf("Welcome to contacts system !\n");
  printf("1. Create contacts\n");
  printf("2. Insert person\n");
  printf("3. Query person\n");
  printf("4. Delete person\n");
  printf("5. Print person\n");
  printf("0. Exit\n");
  printf("Please enter 0-5 to select menu: ");
  for(;;)
  {
    scanf("%d", &sn);
    if(sn < 0 || sn > 5)
      printf("Invalid input, please enter again: ");
    else
      break;
  }  return sn;
}

/***************************************/
/*             用尾插法通信录链表             */
/***************************************/
LinkList CreateList(void)
{
  LinkList head = (LinkList)malloc(sizeof(ListNode));
  ListNode *p, *rear;
  int flag = 0; // 定义录入结束符
  rear = head;
  while (flag == 0)
  {
    // 只要录入不为 0，则不停地采用尾插法建立链表
    p = (ListNode *)malloc(sizeof(ListNode));
    printf("num(5)\tname(9)\tsex(3)\tphone(13)\t\taddr(31)\n");
    printf("------------------------------\n");
    scanf("%s\t%s\t%s\t%s\t\t%s", p->data.num, p->data.name, p->data.sex,p->data.phone,p->data.addr);
    rear->next = p;  // 新结点连接为尾结点的后继
    rear = p;
    printf("Finish? (1/0)");
    scanf("%d", &flag); // 读入一个标识位到 flag
  }
  rear->next = NULL; // 建表结束，最后一个结点的指针域置为NULL
  return head;
}

/***************************************/
/*             通信者结点的插入               */
/***************************************/
void InsertNode(LinkList head, ListNode *p)
{
  ListNode *p1, *p2;
  p1 = head;
  p2 = p1->next; // p2指向第一个结点
  while(p2 != NULL && strcmp(p2->data.num, p->data.num) < 0)
  {
    p1 = p2; // p1 指向刚访问过的结点
    p2 = p2->next; // p2 指向下一个结点
  }
  p1->next = p; // 将新结点插入到 p1 之后
  p->next = p2;
}

/***************************************/
/*             通信者结点的查找               */
/***************************************/
ListNode *ListFind(LinkList head) 
{
  ListNode *p;
  char num[5];
  char name[9];
  int xz;
  printf("=================================\n");
  printf("1. Find by num\n");
  printf("2. Find by name\n");
  printf("=================================\n");
  printf("        Please select       ");
  p = head->next;
  scanf("%d", &xz);
  if(xz == 1)
  {
    printf("Please enter the num: ");
    scanf("%s", num);
    while(p && strcmp(p->data.num, num) < 0)
        p = p->next;
      if (p == NULL || strcmp(p->data.num, num) > 0) 
        p = NULL;
  }
  else
  {
    if (xz == 2) 
    {
      printf("Please enter the name: ");
      scanf("%s", name);
      while(p && strcmp(p->data.name, name) != 0)
        p = p->next;
    }
    return NULL;
  }
  return p;
}

/***************************************/
/*             通信者结点的删除               */
/***************************************/
void DelNode(LinkList head)
{
  char jx[2];
  ListNode *p, *q;
  p = ListFind(head); // 调用查找函数
  if (p == NULL)
  {
    printf("Person Not Found\n");
  }
  else {
    printf("Sure to delete the person? (y/n):");
    scanf("%s", &jx);
    if (jx[0] == 'y' || jx[0] == 'Y')
    {
      q = head;
      while(q != NULL && q->next != p)
        q = q->next;
      q->next = p->next; // 删除节点
      free(p);
      printf("The person is deleted !\n");
    }
    else
      printf("Delete cancel !\n");
  }
}


/***************************************/
/*              通信录链表的输出                */
/***************************************/
void PrintList(LinkList head)
{
  ListNode *p;
  p = head->next; // 使 p 指向第一个结点
    printf("num\t name\t sex\t phone\t addr\n");
  printf("----------------------------------------\n");
  while(p != NULL)
  {
    printf("%s\t %s\t %s\t %s\t %s\n", p->data.num, p->data.name, p->data.sex,p->data.phone,p->data.addr);
    printf("----------------------------------------\n");
    p = p->next;
  }
}

// 定义主函数
int main()
{
  for(;;)
  {
    switch(menu_select())
    {
      case 1:
        printf("***************************************\n");
        printf("*                 Create contacts               *\n");
        printf("***************************************\n");
        head = CreateList();
        break;
      case 2:
        printf("***************************************\n");
        printf("*                    Input nodes                  *\n");
        printf("***************************************\n");
        printf("num(4)  name(8) sex  phone(11)  addr(31)\n");
        printf("***************************************\n");
        p = (ListNode *)malloc(sizeof(ListNode));
        scanf("%s %s %s %s %s", p->data.num, p->data.name, p->data.sex,p->data.phone,p->data.addr);
        InsertNode(head, p);
        break;
      case 3:
        printf("***************************************\n");
        printf("*                    Find person                  *\n");
        printf("***************************************\n");
        p = ListFind(head);
        if(p != NULL)
        {
          printf("num\t name\t sex\t phone\t addr\n");
          printf("----------------------------------------\n");
          printf("%s\t %s\t %s\t %s\t %s\n", p->data.num, p->data.name, p->data.sex, p->data.phone, p->data.addr);
          printf("----------------------------------------\n");
        }
        else 
          printf("Not Found\n");
        break;
      case 4:
        printf("***************************************\n");
        printf("*                  Delete person                *\n");
        printf("***************************************\n");
        DelNode(head);
        break;
      case 5:
        printf("***************************************\n");
        printf("*                Print contacts list             *\n");
        printf("***************************************\n");
        PrintList(head);
        break;
      case 0:
        printf("\t Exit System. \n");
      return 0;
    }
  }
  return 0;
}